package app

import (
	"bzppx-codepub-server/app/container"
	"bzppx-codepub-server/app/controllers"
	"bzppx-codepub-server/app/models"
	"bzppx-codepub-server/app/utils"
	"flag"
	"fmt"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/logs"
	"github.com/gogf/gf/g/os/glog"
	"github.com/snail007/go-activerecord/mysql"
	"github.com/spf13/afero"
	"log"
	"net/http"
	"os"
)

var (
	confPath = flag.String("conf", "conf/default.conf", "please set codepub conf path")
	Version  = "v0.8.4"
	AppFs    = afero.NewOsFs()
)

// 项目启动入口
func init() {
	poster()     // 显示logo
	initConfig() // 初始化配置
	InitDB()     // 初始化数据库
	initRouter() // 初始化路由

	container.InitWorker() // 初始化工作
}

// poster logo
func poster() {
	glog.SetFlags(glog.F_TIME_STD | glog.F_FILE_LONG)
	glog.SetPath("logs")
	logo := `
                    __                     __
  _____ ____   ____/ /___   ____   __  __ / /_
 / ___// __ \ / __  // _ \ / __ \ / / / // __ \
/ /__ / /_/ // /_/ //  __// /_/ // /_/ // /_/ /
\___/ \____/ \__,_/ \___ / .___/ \__,_//_.___/
                        /_/
` +
		"Author: bzppx\r\n" +
		"Version: " + Version + "\r\n" +
		"Link: https://github.com/bzppx/bzppx-codepub"
	fmt.Println(logo)
}

// init beego config 初始化配置
func initConfig() {
	flag.Parse()

	// 检查配置文件
	if *confPath == "" {
		log.Println("配置文件不能为空!")
		os.Exit(1)
	}
	ok, _ := afero.Exists(AppFs, *confPath)
	if !ok {
		log.Println("配置文件: " + *confPath + " 不存在!")
		os.Exit(1)
	}

	// 设置配置文件类型为ini, 加载配置文件
	beego.LoadAppConfig("ini", *confPath)

	// 设置应用名字 init name
	beego.AppConfig.Set("sys.name", "codepub")
	beego.BConfig.AppName = beego.AppConfig.String("sys.name")
	beego.BConfig.ServerName = beego.AppConfig.String("sys.name")

	// set static path 静态资源目录
	beego.SetStaticPath("/static/", "static")

	// views path 视图文件目录
	beego.BConfig.WebConfig.ViewsPath = "views/"

	// sessions设置
	beego.BConfig.WebConfig.Session.SessionName = "ssid"
	beego.BConfig.WebConfig.Session.SessionOn = true

	// log设置
	logConfigs, err := beego.AppConfig.GetSection("log")
	if err != nil {
		log.Println(err.Error())
	}
	for adapter, config := range logConfigs {
		logs.SetLogger(adapter, config)
	}
	logs.EnableFuncCallDepth(true)

}

// 初始化数据库
func InitDB() {
	// 连接数据库信息
	host := beego.AppConfig.String("db::host")
	port, _ := beego.AppConfig.Int("db::port")
	user := beego.AppConfig.String("db::user")
	pass := beego.AppConfig.String("db::pass")
	dbname := beego.AppConfig.String("db::name")
	dbTablePrefix := beego.AppConfig.String("db::table_prefix")  // 表名前缀
	maxIdle, _ := beego.AppConfig.Int("db::conn_max_idle")       // 最大空闲连接
	maxConn, _ := beego.AppConfig.Int("db::conn_max_connection") // 最大连接数

	// 设置默认数据库
	models.G = mysql.NewDBGroup("default")
	cfg := mysql.NewDBConfigWith(host, port, dbname, user, pass)
	cfg.SetMaxIdleConns = maxIdle
	cfg.SetMaxOpenConns = maxConn
	cfg.TablePrefix = dbTablePrefix
	cfg.TablePrefixSqlIdentifier = "__PREFIX__"
	err := models.G.Regist("default", cfg)
	if err != nil {
		logs.Error(fmt.Errorf("database error:%s,with config : %v", err, cfg))
		os.Exit(100)
	}
}

// 404页面
func http_404(rs http.ResponseWriter, req *http.Request) {
	rs.Write([]byte("404 not found,页面没找到!"))
}

// 500页面
func http_500(rs http.ResponseWriter, req *http.Request) {
	rs.Write([]byte("500 server error!"))
}

// 初始化路由
func initRouter() {
	// router
	beego.BConfig.WebConfig.AutoRender = false                                                             // 是否模板自动渲染，默认值为 true，对于 API 类型的应用，应用需要把该选项设置为 false，不需要渲染模板。
	beego.BConfig.RouterCaseSensitive = false                                                              // 路由区分大小写
	beego.BConfig.WebConfig.Session.SessionCookieLifeTime, _ = beego.AppConfig.Int("sessiongcmaxlifetime") // session 时长

	beego.AutoRouter(&controllers.LoginController{})      // 登录
	beego.AutoRouter(&controllers.ProfileController{})    // 个人中心
	beego.AutoRouter(&controllers.PublishController{})    // 项目列表
	beego.AutoRouter(&controllers.TaskController{})       // 任务队列
	beego.AutoRouter(&controllers.TaskLogController{})    // 任务日志列表
	beego.AutoRouter(&controllers.ContactController{})    // 联系人
	beego.AutoRouter(&controllers.UserController{})       // 用户管理
	beego.AutoRouter(&controllers.GroupController{})      // 项目组
	beego.AutoRouter(&controllers.ProjectController{})    // 项目
	beego.AutoRouter(&controllers.NoticeController{})     // 公告管理
	beego.AutoRouter(&controllers.NodeController{})       // 节点控制器
	beego.AutoRouter(&controllers.NodesController{})      // 节点组控制器
	beego.AutoRouter(&controllers.ConfigureController{})  // 封板,邮件配置
	beego.AutoRouter(&controllers.ApiAuthController{})    // 认证管理
	beego.AutoRouter(&controllers.StatisticsController{}) // 发布统计列表
	beego.AutoRouter(&controllers.LogController{})        // 日志管理
	beego.AutoRouter(&controllers.MainController{})       // 主控制器
	beego.Router("/", &controllers.LoginController{}, "*:Index")

	beego.ErrorHandler("404", http_404)
	beego.ErrorHandler("500", http_500)

	// add template func
	beego.AddFuncMap("dateFormat", utils.NewDate().Format)
}
